package com.zd.bms.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.zd.bms.bean.vo.MenuTreeVo;
import com.zd.bms.bean.vo.req.BmsUserListReqVo;
import com.zd.bms.bean.vo.resp.BmsUserRespVo;
import com.zd.bms.service.IBmsUserService;
import com.zd.bms.service.IScenicSpotService;
import com.zd.common.bean.model.BmsResource;
import com.zd.common.bean.model.BmsRole;
import com.zd.common.bean.model.BmsRoleResource;
import com.zd.common.bean.model.BmsUser;
import com.zd.common.bean.model.BmsUserRole;
import com.zd.common.bean.model.ScenicSpot;
import com.zd.common.common.enums.BmsUserTypeEnum;
import com.zd.common.common.enums.StatusEnum;
import com.zd.common.common.utils.EncryptUtil;
import com.zd.common.common.utils.StringUtils;
import com.zd.common.dao.BmsResourceDao;
import com.zd.common.dao.BmsRoleDao;
import com.zd.common.dao.BmsRoleResourceDao;
import com.zd.common.dao.BmsUserDao;
import com.zd.common.dao.BmsUserRoleDao;
import com.zd.common.dao.common.BaseDao;
import com.zd.common.dao.common.FindRequestEntity;
import com.zd.common.dao.common.OrderEnum;
import com.zd.common.dao.common.Page;
import com.zd.common.dao.common.WhereEnum;
import com.zd.common.service.impl.BaseServiceImpl;

@Service
public class BmsUserServiceImpl extends BaseServiceImpl<BmsUser> implements IBmsUserService {
	@Autowired
	private BmsUserDao bmsUserDao;

	@Autowired
	private BmsUserRoleDao bmsUserRoleDao;

	@Autowired
	private BmsRoleDao bmsRoleDao;

	@Autowired
	private BmsRoleResourceDao bmsRoleResourceDao;

	@Autowired
	private BmsResourceDao bmsResourceDao;

	@Autowired
	private IScenicSpotService scenicSpotService;

	@Override
	public BaseDao<BmsUser> getBaseDao() {
		return bmsUserDao;
	}

	@Override
	public BmsUser findUser(String username, String password) throws Exception {
		FindRequestEntity findUserReq = new FindRequestEntity();
		findUserReq.addWhere("ent_no", WhereEnum.EQ, username);
		findUserReq.addWhere("status", WhereEnum.NE, StatusEnum.delete.getKey());
		findUserReq.addWhere("password", WhereEnum.EQ, EncryptUtil.getMD5(password));

		List<BmsUser> bmsUserList = find(findUserReq);
		if (bmsUserList != null && bmsUserList.size() > 0) {
			return bmsUserList.get(0);
		}
		return null;
	}
	
	public BmsUser findUser(String username) throws Exception {
		FindRequestEntity findUserReq = new FindRequestEntity();
		findUserReq.addWhere("ent_no", WhereEnum.EQ, username);

		List<BmsUser> bmsUserList = find(findUserReq);
		if (bmsUserList != null && bmsUserList.size() > 0) {
			return bmsUserList.get(0);
		}
		return null;
	}

	public Map<String, Object> loadBmsUserRoleResource(BmsUser bmsUser) throws Exception {
		Map<String, Object> resultMap = new HashMap<>();
		/**
		 * 处理三件事 
		 *  1、获取角色名
		 *  2、获取菜单树，用于展示 
		 *  3、获取资源列表，用于权限控制
		 *  
		 */

		if (bmsUser == null || bmsUser.getId() == null) {
			return resultMap;
		}
		resultMap.put("user", bmsUser);

		// 找出用户所有资源
		FindRequestEntity findUserRoleReq = new FindRequestEntity();
		findUserRoleReq.addWhere("user_id", WhereEnum.EQ, bmsUser.getId());
		List<BmsUserRole> useRoleList = bmsUserRoleDao.find(findUserRoleReq);
		Set<BmsResource> resourceSet = new HashSet<>();
		if (useRoleList != null && useRoleList.size() > 0) {
			// 用户角色名 ，只展示第一个
			BmsRole role = bmsRoleDao.get(useRoleList.get(0).getRoleId());
			if (role != null) {
				// 1、获取一个角色名，用于显示
				resultMap.put("roleName", role.getName());
			}

			for (BmsUserRole userRole : useRoleList) {
				FindRequestEntity findResourceReq = new FindRequestEntity();
				findResourceReq.addWhere("role_id", WhereEnum.EQ, userRole.getRoleId());

				List<BmsRoleResource> roleResourceList = bmsRoleResourceDao.find(findResourceReq);
				if (roleResourceList != null && roleResourceList.size() > 0) {
					for (BmsRoleResource roleResource : roleResourceList) {
						BmsResource resource = bmsResourceDao.get(roleResource.getResourceId());
						if (resource != null) {
							resourceSet.add(resource);
						}
					}
				}
			}

			if (resourceSet.size() == 0) {
				return resultMap;
			}

			// step 2、获得菜单树
			// 排序
			List<BmsResource> resourceList = new ArrayList<>();
			resourceList.addAll(resourceSet);
			Collections.sort(resourceList);
			List<MenuTreeVo> menuTreeList = new ArrayList<>();
			// 获取顶级菜单
			for (BmsResource leve1Resource : resourceList) {
				if (leve1Resource.getLevel() == 1) {
					MenuTreeVo topMenuTree = new MenuTreeVo();
					topMenuTree.setId(leve1Resource.getId());
					topMenuTree.setName(leve1Resource.getName());
					topMenuTree.setUrl(leve1Resource.getUrl());
					List<MenuTreeVo> level2TreeList = new ArrayList<>();
					// 获取二级菜单
					for (BmsResource leve2Resource : resourceList) {
						if (leve1Resource.getId().equals(leve2Resource.getParentId())) {
							MenuTreeVo level2Tree = new MenuTreeVo();
							level2Tree.setId(leve2Resource.getId());
							level2Tree.setName(leve2Resource.getName());
							level2Tree.setUrl(leve2Resource.getUrl());
							List<MenuTreeVo> level3TreeList = new ArrayList<>();
							//获取三级菜单 （菜单一共只有三层）
							for (BmsResource level3Resource : resourceList) {
								if (leve2Resource.getId().equals(level3Resource.getParentId())) {
									MenuTreeVo level3Tree = new MenuTreeVo();
									level3Tree.setId(level3Resource.getId());
									level3Tree.setName(level3Resource.getName());
									level3Tree.setUrl(level3Resource.getUrl());
									level3TreeList.add(level3Tree);
								}
							}
							level2Tree.setChildTree(level3TreeList);
							level2TreeList.add(level2Tree);
						}
					}
					topMenuTree.setChildTree(level2TreeList);
					menuTreeList.add(topMenuTree);
				}
			}
			resultMap.put("menuTree", menuTreeList);

			// step 3、获取资源列表
			Set<String> resourceUrlList = new HashSet<>();
			for (BmsResource bmsResource : resourceList) {
				if (!StringUtils.isBank(bmsResource.getUrl())) {
					resourceUrlList.add(bmsResource.getUrl());
				}
			}
			resultMap.put("resourceList", resourceUrlList);
		}
		return resultMap;
	}

	@Override
	public Page<BmsUserRespVo> pageBmsUser(BmsUserListReqVo req) throws Exception {
		FindRequestEntity findReq = new FindRequestEntity();
		if (!StringUtils.isBank(req.getEntNo())) {
			findReq.addWhere("ent_no", WhereEnum.LIKE, "%" + req.getEntNo() + "%");
		}

		if (req.getType() != null) {
			findReq.addWhere("type", WhereEnum.EQ, req.getType());
		}

		if (req.getStatus() != null) {
			findReq.addWhere("status", WhereEnum.EQ, req.getStatus());
		}

		if (req.getScenicSpotId() != null) {
			findReq.addWhere("scenic_spot_id", WhereEnum.EQ, req.getScenicSpotId());
		}

		findReq.addWhere("status", WhereEnum.NE, StatusEnum.delete.getKey());

		findReq.addOrder("create_time", OrderEnum.DESC);

		Page<BmsUser> scenicSpotPage = page(findReq);
		Page<BmsUserRespVo> resultPage = new Page<>();
		resultPage.setPage(scenicSpotPage.getPage());
		resultPage.setPageSize(scenicSpotPage.getPageSize());
		resultPage.setTotalRow(scenicSpotPage.getTotalRow());
		List<BmsUser> list = scenicSpotPage.getList();
		List<BmsUserRespVo> resultVoList = new ArrayList<>();

		//获取景区
		Map<Integer, ScenicSpot> scenicSpotMap = new HashMap<>();
		for (BmsUser bmsUser : list) {
			BmsUserRespVo respVo = new BmsUserRespVo();
			BeanUtils.copyProperties(bmsUser, respVo);

			//获取景区信息
			ScenicSpot scenicSpot = scenicSpotMap.get(bmsUser.getScenicSpotId());
			if (scenicSpot == null) {
				scenicSpot = scenicSpotService.get(bmsUser.getScenicSpotId());
				scenicSpotMap.put(bmsUser.getScenicSpotId(), scenicSpot);
			}
			if (scenicSpot != null) {
				respVo.setScenicSpotName(scenicSpot.getName());
			}
			resultVoList.add(respVo);
		}
		resultPage.setList(resultVoList);
		return resultPage;
	}

	@Override
	public Map<String, Object> saveOrUpdateUser(BmsUser bmsUser) throws Exception {
		Map<String, Object> resultMap = new HashMap<>();
		BmsUser originBmsUser = null;
		if (bmsUser.getId() != null) {
			originBmsUser = get(bmsUser.getId());
			//TODO 给用户更新角色信息 （暂时用户类型和角色绑定死，角色只设置3种，以后可以扩充让管理员自己选择）
			if (!originBmsUser.getType().equals(bmsUser.getType())) {
				FindRequestEntity findReq = new FindRequestEntity();
				findReq.addWhere("user_id", WhereEnum.EQ, bmsUser.getId());
				List<BmsUserRole> bmsUserRoleList = bmsUserRoleDao.find(findReq);
				if (bmsUserRoleList != null && bmsUserRoleList.size() > 0) {
					BmsUserRole bmsUserRole = bmsUserRoleList.get(0);
					if (BmsUserTypeEnum.Platform_user.getKey() == bmsUser.getType()) {
						bmsUserRole.setRoleId(6);
					} else if (BmsUserTypeEnum.Scenic_area_administrator.getKey() == bmsUser.getType()) {
						bmsUserRole.setRoleId(1);
					} else if (BmsUserTypeEnum.Scenic_spot_conductor.getKey() == bmsUser.getType()) {
						bmsUserRole.setRoleId(2);
					}
					bmsUserRole.setUpdateTime(new Date());
					bmsUserRoleDao.update(bmsUserRole);
				}
			}

			BeanUtils.copyProperties(bmsUser, originBmsUser, "status", "password", "createTime", "updateTime");
			if (BmsUserTypeEnum.Platform_user.getKey() == originBmsUser.getType()) {
				originBmsUser.setScenicSpotId(0);
			}
			originBmsUser.setUpdateTime(new Date());
			update(originBmsUser);

		} else {
			originBmsUser = new BmsUser();
			BmsUser existUser = findUser(bmsUser.getEntNo());
			if(existUser != null) {
				resultMap.put("result", false);
				resultMap.put("errorMsg", "该账号已经被注册");
				return resultMap;
			}
			
			BeanUtils.copyProperties(bmsUser, originBmsUser, "status", "password", "createTime", "updateTime");
			originBmsUser.setPassword(EncryptUtil.getMD5("abc123"));
			originBmsUser.setCreateTime(new Date());
			originBmsUser.setUpdateTime(new Date());
			if (BmsUserTypeEnum.Platform_user.getKey() == originBmsUser.getType()) {
				originBmsUser.setScenicSpotId(0);
			}
			insert(originBmsUser);

			//TODO 给用户角色信息 （暂时用户类型和角色绑定死，角色只设置3种，以后可以扩充让管理员自己选择）
			BmsUserRole bmsUserRole = new BmsUserRole();
			bmsUserRole.setUserId(originBmsUser.getId());
			if (BmsUserTypeEnum.Platform_user.getKey() == bmsUser.getType()) {
				bmsUserRole.setRoleId(6);
			} else if (BmsUserTypeEnum.Scenic_area_administrator.getKey() == bmsUser.getType()) {
				bmsUserRole.setRoleId(1);
			} else if (BmsUserTypeEnum.Scenic_spot_conductor.getKey() == bmsUser.getType()) {
				bmsUserRole.setRoleId(2);
			}
			bmsUserRole.setCreateTime(new Date());
			bmsUserRole.setUpdateTime(new Date());
			bmsUserRoleDao.insert(bmsUserRole);
		}
		resultMap.put("result", true);
		return resultMap;
	}

	@Override
	public Map<String, Object> updatePwd(String oldPwd, String newPwd, BmsUser bmsUser) throws Exception {
		Map<String, Object> resultMap = new HashMap<>();
		if(bmsUser.getPassword().equals(EncryptUtil.getMD5(oldPwd))){
			bmsUser.setPassword(EncryptUtil.getMD5(newPwd));
			bmsUser.setUpdateTime(new Date());
			bmsUserDao.update(bmsUser);
			resultMap.put("result", true);
			resultMap.put("msg", "修改成功");
			return resultMap;
		}
		resultMap.put("result", false);
		resultMap.put("msg", "当前密码输入不正确");
		return resultMap;
	}
}
